<!DOCTYPE html>
<html lang="en-US">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width,initial-scale=1">
    <title>2019/6/4日 Vue作者尤雨溪技在深圳术分享内容 | Jayken (谢小舜)|谢小舜的个人博客</title>
    <meta name="description" content=" Jayken（谢小舜）的个人主页，记录我的程序员职业成长之路，分享前端、Java踩过的坑！">
    
    
    <link rel="preload" href="/assets/css/0.styles.0c98b5d4.css" as="style"><link rel="preload" href="/assets/js/app.2d175a42.js" as="script"><link rel="preload" href="/assets/js/2.af4947b8.js" as="script"><link rel="preload" href="/assets/js/13.71248d26.js" as="script"><link rel="prefetch" href="/assets/js/10.ead388bb.js"><link rel="prefetch" href="/assets/js/11.c26367e4.js"><link rel="prefetch" href="/assets/js/12.e15eef2b.js"><link rel="prefetch" href="/assets/js/14.caa891a6.js"><link rel="prefetch" href="/assets/js/15.dba29244.js"><link rel="prefetch" href="/assets/js/3.8c0cb32d.js"><link rel="prefetch" href="/assets/js/4.ea6b297e.js"><link rel="prefetch" href="/assets/js/5.e528d392.js"><link rel="prefetch" href="/assets/js/6.d3c0fe75.js"><link rel="prefetch" href="/assets/js/7.f9e4b783.js"><link rel="prefetch" href="/assets/js/8.cfbdc4b7.js"><link rel="prefetch" href="/assets/js/9.e68d7ec2.js">
    <link rel="stylesheet" href="/assets/css/0.styles.0c98b5d4.css">
  </head>
  <body>
    <div id="app" data-server-rendered="true"><div class="theme-container no-sidebar"><header class="navbar"><div class="navbar-wrap"><div><div class="sidebar-button"><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" role="img" viewBox="0 0 448 512" class="icon"><path fill="currentColor" d="M436 124H12c-6.627 0-12-5.373-12-12V80c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12z"></path></svg></div> <a href="/" class="home-link router-link-active"><img src="/images/logo_z.gif" alt="Jayken (谢小舜)|谢小舜的个人博客" class="logo"> <!----></a> <nav class="nav-links can-hide"><div class="nav-item"><a href="/" class="nav-link">首页</a></div><div class="nav-item"><a href="/post/" class="nav-link router-link-active">博客</a></div><div class="nav-item"><a href="https://github.com/jaykenxie" target="_blank" rel="noopener noreferrer" class="nav-link external">
  GitHub
  <svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a></div> <!----></nav></div> <div class="links"><div class="search-box"><input aria-label="Search" autocomplete="off" spellcheck="false" value=""> <!----></div></div></div></header> <div class="sidebar-mask"></div> <aside class="sidebar"><nav class="nav-links"><div class="nav-item"><a href="/" class="nav-link">首页</a></div><div class="nav-item"><a href="/post/" class="nav-link router-link-active">博客</a></div><div class="nav-item"><a href="https://github.com/jaykenxie" target="_blank" rel="noopener noreferrer" class="nav-link external">
  GitHub
  <svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a></div> <!----></nav>  <!----> </aside> <main class="page"><div class="page-left"><div class="page-content"><div class="page-title"><h3>2019/6/4日 Vue作者尤雨溪技在深圳术分享内容</h3> <div class="page-title_info"><span class="page-title_author"><img src="https://avatars3.githubusercontent.com/u/29194135?v=4" alt class="page-title_avatar"> <span>谢小舜</span></span> <span class="page-title_time"><span>2019-10-10 02:55:36</span></span></div></div> <div class="theme-content content__default"><p>Vue 作者 尤雨溪 2019.06.04 在深圳平安金融中心开了一场技术分享会，将内容整理一下</p> <h1 id="大纲"><a href="#大纲" aria-hidden="true" class="header-anchor">#</a> 大纲</h1> <ul><li>Vue 团队和发展现状介绍</li> <li>设计思路及与其它框架的比较</li> <li>生态介绍和方案推荐</li> <li>--- 午休 ---</li> <li>3.0 新特性、改动介绍</li> <li>Vue 的培训和学习路线 &amp; QA</li></ul> <h1 id="团队发展现状"><a href="#团队发展现状" aria-hidden="true" class="header-anchor">#</a> 团队发展现状</h1> <ul><li>Chrome DevTools: 93.2 万周活跃用户 - 对比:React ~160 万</li> <li>npm 下载量:~400 万次/月</li> <li>Jsdelivr CDN:5 亿次引用/月</li> <li>GitHub stars:13.6 万
<ul><li>全 GitHub 第三，实际代码项目第一</li></ul></li></ul> <h1 id="全球化的影响力"><a href="#全球化的影响力" aria-hidden="true" class="header-anchor">#</a> 全球化的影响力</h1> <ul><li>遍布世界各地的线下聚会 https://events.vuejs.org/</li> <li>目前每年在世界各地举办的 Vue 主题会议:
<ul><li>VueConf 中国</li> <li>Vue.js Amsterdam(欧洲)</li> <li>VueConf US(美国)</li> <li>Vue Fes Japan(日本)</li> <li>VueConf Toronto(加拿大)</li> <li>VueDay Italy(欧洲)</li> <li>Vue Summit Brazil(南美)</li></ul></li></ul> <h2 id="良好的反馈"><a href="#良好的反馈" aria-hidden="true" class="header-anchor">#</a> 良好的反馈</h2> <ul><li>State of JavaScript 2018 调查
<ul><li>前端框架满意度第一 (91%)</li></ul></li> <li>StackOverflow 2019 年度调查
<ul><li>Most Loved Web Frameworks 第二</li></ul></li></ul> <h1 id="使用公司遍布全球"><a href="#使用公司遍布全球" aria-hidden="true" class="header-anchor">#</a> 使用公司遍布全球</h1> <p><img src="https://blog-1251280787.cos.ap-shanghai.myqcloud.com/undefined1964-1.png" alt="1964-1.png"></p> <h1 id="团队"><a href="#团队" aria-hidden="true" class="header-anchor">#</a> 团队</h1> <p><img src="https://blog-1251280787.cos.ap-shanghai.myqcloud.com/undefined~imgvue1964-2.png" alt="~imgvue1964-2.png"> <img src="https://blog-1251280787.cos.ap-shanghai.myqcloud.com/undefined1964-3.png" alt="1964-3.png"> <img src="https://blog-1251280787.cos.ap-shanghai.myqcloud.com/undefined1964-4.png" alt="1964-4.png"> <img src="https://blog-1251280787.cos.ap-shanghai.myqcloud.com/undefined1964-5" alt="1964-5"> <img src="https://blog-1251280787.cos.ap-shanghai.myqcloud.com/undefined2019-10-10-1964-6.png" alt="2019-10-10-1964-6.png"> <img src="https://blog-1251280787.cos.ap-shanghai.myqcloud.com/undefined2019-10-10-1964-7.png" alt="2019-10-10-1964-7.png"> <img src="https://blog-1251280787.cos.ap-shanghai.myqcloud.com/undefined2019-10-10-1964-8.png" alt="2019-10-10-1964-8.png"> <img src="https://blog-1251280787.cos.ap-shanghai.myqcloud.com/undefined2019-10-10-1964-9.png" alt="2019-10-10-1964-9.png"> <img src="https://blog-1251280787.cos.ap-shanghai.myqcloud.com/undefined2019-10-10.png" alt="2019-10-10.png"> <img src="https://blog-1251280787.cos.ap-shanghai.myqcloud.com/undefined2019-10-10-1964-11.png" alt="2019-10-10-1964-11.png"> <img src="https://blog-1251280787.cos.ap-shanghai.myqcloud.com/undefined2019-10-10-1964-12.png" alt="2019-10-10-1964-12.png"> <img src="https://blog-1251280787.cos.ap-shanghai.myqcloud.com/undefined2019-10-10-1964-13.png" alt="2019-10-10-1964-13.png"> <img src="https://blog-1251280787.cos.ap-shanghai.myqcloud.com/undefined2019-10-10-1964-14.png" alt="2019-10-10-1964-14.png"> <img src="https://blog-1251280787.cos.ap-shanghai.myqcloud.com/undefined2019-10-10-1964-15.png" alt="2019-10-10-1964-15.png"></p> <h2 id="对比-angular"><a href="#对比-angular" aria-hidden="true" class="header-anchor">#</a> 对比 Angular</h2> <ul><li>更灵活的适应各种场景
<ul><li>默认 API 适合纯前端背景的开发者 / 小快灵场景</li> <li>配合 TypeScript 也可以适合传统 Java 后端背景的开发者 / 大型项目</li></ul></li> <li>更低的培训成本，更快的上手 􏰀 度</li> <li>底层的 Virtual DOM 在高级场景下提供更多的灵活性</li> <li>大型应用中与 TypeScript 的整合不如 Angular
<ul><li>3.0 中会针对性增强</li></ul></li></ul> <h2 id="对比-react"><a href="#对比-react" aria-hidden="true" class="header-anchor">#</a> 对比 React</h2> <ul><li>对大部分常见场景都提供了事实标准方案
<ul><li>不需要额外自行调研选取方案</li> <li>在必要情况下也可以 换用自研方案</li></ul></li> <li>模版提供更友好的学习曲线
<ul><li>同时暴露底层 Virtual DOM 用于高级场景(也支持 JSX)</li></ul></li> <li>大型应用中与 TypeScript 的整合暂时不如 React
<ul><li>3.0 中会针对性增强，尤其是 TSX</li></ul></li> <li>对标 React 16+
<ul><li>Vue 同样可以实现类似 Hooks 的逻辑复用机制</li> <li>3.0 支持时间分片</li></ul></li></ul> <h2 id="与其它所有框架的区别"><a href="#与其它所有框架的区别" aria-hidden="true" class="header-anchor">#</a> 与其它所有框架的区别</h2> <ul><li>自带的响应式系统 (Reactivity System)
<ul><li>类似于 MobX，但与框架本身的整合更无 缝</li> <li>在复杂组件树中提供比 React 更精确的更新 侦测</li> <li>3.0 将暴露更多底 层响应式 API</li></ul></li> <li>单文件组件 (Single File Components)
<ul><li>HTML 的自然延伸，符合直 觉的代码组织方式</li> <li>完善的工具 链
<ul><li>预处理器支持</li> <li>Scoped CSS</li> <li>webpack 热更新</li> <li>IDE 支持 (VSCode + Vetur)</li> <li>Linter 支持 (eslint-plugin-vue)</li></ul></li></ul></li></ul> <p><img src="https://blog-1251280787.cos.ap-shanghai.myqcloud.com/undefined2019-10-10-1964-16.png" alt="2019-10-10-1964-16.png"> <img src="https://blog-1251280787.cos.ap-shanghai.myqcloud.com/undefined2019-10-10-1964-17.png" alt="2019-10-10-1964-17.png"> <img src="https://blog-1251280787.cos.ap-shanghai.myqcloud.com/undefined2019-10-10-1964-18.png" alt="2019-10-10-1964-18.png"></p> <h2 id="官方工具链"><a href="#官方工具链" aria-hidden="true" class="header-anchor">#</a> 官方工具链</h2> <ul><li>路由:vue-router</li> <li>状态管理:vuex</li> <li>构建工具脚手架:vue-cli</li> <li>开发者工具:vue-devtools</li> <li>IDE 支持:VSCode + Vetur</li> <li>静态检查:ESLint + eslint-plugin-vue</li> <li>单元测试:Jest + vue-jest + vue-test-utils</li> <li>文档/静态站生成:VuePress</li></ul> <h2 id="优秀的组件库"><a href="#优秀的组件库" aria-hidden="true" class="header-anchor">#</a> 优秀的组件库</h2> <ul><li>Vuetify
<ul><li>基于 Material Design，功能完整强大，桌面 + 移动</li> <li>支持 SSR</li></ul></li> <li>Element-UI
<ul><li>知名国产组件库，来自饿了么前端团队</li> <li>只支持桌面端 应用</li> <li>有现成的控制后台模版</li></ul></li> <li>iView
<ul><li>另一个知名国 产库，来自 TalkingData 前端团队</li> <li>主要支持桌面端，但也有小程序整合</li> <li>有现成的控制后台模版</li></ul></li></ul> <h2 id="优秀的组件库-2"><a href="#优秀的组件库-2" aria-hidden="true" class="header-anchor">#</a> 优秀的组件库</h2> <ul><li>Quasar
<ul><li>不仅仅是组件库的全平台解决方案</li> <li>桌面端 SPA/SSR + 移动端 PWA / Hybrid + 桌面端 Electron。</li></ul></li></ul> <h2 id="上层框架-nuxt-js"><a href="#上层框架-nuxt-js" aria-hidden="true" class="header-anchor">#</a> 上层框架 - Nuxt.js</h2> <ul><li>开箱即用的 SSR 封装</li> <li>也支持 SPA / 静态生成模式 - 有商业支持</li></ul> <h2 id="移动端方案-h5-hybrid-vant"><a href="#移动端方案-h5-hybrid-vant" aria-hidden="true" class="header-anchor">#</a> 移动端方案(H5 / Hybrid) - Vant</h2> <ul><li>来自有赞的纯移动端 web 组件库 - Vux</li> <li>基于微信 UI 风格的移动端 web 组件库</li> <li>Onsen UI
<ul><li>来自日本，基于 custom elements 支持多个上层框架的 hybrid 移动端方案</li></ul></li> <li>Ionic 4
<ul><li>知名 hybrid 移动端方案，原本只支持 Angular，4.0 开始通过原生 custom elements 支持 Vue
(目前 beta)</li></ul></li></ul> <h2 id="移动端方案-native"><a href="#移动端方案-native" aria-hidden="true" class="header-anchor">#</a> 移动端方案(Native)</h2> <ul><li>Weex
<ul><li>来自阿里，现为 Apache 基金会项目</li> <li>在阿里内部广泛使用， 经受过考验</li> <li>有一定的国内社区</li></ul></li> <li>NativeScript
<ul><li>原本只支持 Angular，但现在大力投入与 Vue 的整合</li> <li>完善的文档和活 跃的国外社区，但大多 为英文</li> <li>作为产品，背后有商 业投入，提供商 业支持</li></ul></li> <li>Uni-app
<ul><li>国产的 Vue 跨端方案，来自 DCloud</li> <li>同一套代码编译到 iOS, Android, H5 + 多种小程序</li></ul></li></ul> <h1 id="_3-0-新特性-改动"><a href="#_3-0-新特性-改动" aria-hidden="true" class="header-anchor">#</a> 3.0 新特性 / 改动</h1> <h2 id="_3-0-设计目标"><a href="#_3-0-设计目标" aria-hidden="true" class="header-anchor">#</a> 3.0 设计目标</h2> <ul><li>更小</li> <li>更快</li> <li>加强 API 设计一致性</li> <li>加强 TypeScript 支持</li> <li>提高自身可维护性</li> <li>开放更多底层功能</li></ul> <h3 id="更小"><a href="#更小" aria-hidden="true" class="header-anchor">#</a> 更小</h3> <ul><li>全局 API 和内置组件 / 功能支持 tree-shaking</li> <li>常驻的代码尺寸控制在 10kb gzipped 上下</li></ul> <h3 id="更快"><a href="#更快" aria-hidden="true" class="header-anchor">#</a> 更快</h3> <ul><li>基于 Proxy 的变动侦测，性能整体优于 getter / setter
<ul><li>长远来看，JS 引擎会继续优化 Proxy，但 getter / setter 基本不会再有针对
性的优化</li></ul></li> <li>Virtual DOM 重构
<ul><li>更新 􏰀 度 / 内存占用均有质的提升</li></ul></li> <li>编译器架构重构，更多的编译时优化</li></ul> <h3 id="提高自身可维护性"><a href="#提高自身可维护性" aria-hidden="true" class="header-anchor">#</a> 提高自身可维护性</h3> <ul><li>代码采用 monorepo 结构，内部分层更清晰</li> <li>TypeScript 使得外部贡献者更有信心做改动
开放更多底层功能
<ul><li>Custom Renderer</li></ul> <div class="language-javascript line-numbers-mode"><pre class="language-javascript"><code><span class="token keyword">import</span> <span class="token punctuation">{</span> createRenderer <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">&quot;@vue/runtime-core&quot;</span><span class="token punctuation">;</span>
<span class="token keyword">const</span> <span class="token punctuation">{</span> render <span class="token punctuation">}</span> <span class="token operator">=</span> <span class="token function">createRenderer</span><span class="token punctuation">(</span><span class="token punctuation">{</span>
  nodeOps<span class="token punctuation">,</span>
  patchData
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br></div></div></li></ul> <h3 id="传统-vdom-的性能瓶颈"><a href="#传统-vdom-的性能瓶颈" aria-hidden="true" class="header-anchor">#</a> 传统 vdom 的性能瓶颈</h3> <ul><li>虽然 Vue 能够保证触发更新的组件最小化，但在单个组件内 部依然需要遍历该组件的整个 vdom 树</li> <li>在一些组件整个模版内只有少量动态节点的情况下，这些遍 历都是性能的浪费</li> <li>传统 vdom 的性能跟模版大小正相关，跟动态节点的数量无 关</li></ul> <h3 id="动静结合突破瓶颈"><a href="#动静结合突破瓶颈" aria-hidden="true" class="header-anchor">#</a> 动静结合突破瓶颈</h3> <ul><li>通过模版静态分析生成更优化的 vdom 渲染函数</li> <li>将模版切分为 block(if, for, slot)，每个 block 内部动态节点
位置是固定的</li> <li>每个 block 的根节点会记录自己所包含的动态节点(包含子
block 的根节点)</li> <li>更新时只需要直接遍历动态节点</li></ul> <h3 id="动静结合突破瓶颈-2"><a href="#动静结合突破瓶颈-2" aria-hidden="true" class="header-anchor">#</a> 动静结合突破瓶颈</h3> <ul><li>新策略将 vdom 更新性能与模版大小解耦，变为与动态节点 的数量相关</li> <li>整体比 Vue 2 性能提升 2~5 倍</li></ul> <h3 id="typescript"><a href="#typescript" aria-hidden="true" class="header-anchor">#</a> TypeScript</h3> <ul><li>3.0 本身用 TypeScript 重写，内置 typing - TSX 支持</li> <li>不会影响不使用 TS 的用户
TypeScript
重要的事情说三遍</li> <li>Class API 提案已撤销</li> <li>Class API 提案已撤销</li> <li>Class API 提案已撤销</li></ul> <h3 id="function-based-api"><a href="#function-based-api" aria-hidden="true" class="header-anchor">#</a> Function-based API</h3> <div class="language-javascript line-numbers-mode"><pre class="language-javascript"><code><span class="token keyword">const</span> App <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token function">setup</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// data</span>
<span class="token keyword">const</span> count <span class="token operator">=</span> <span class="token function">value</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">)</span>
<span class="token comment">// computed</span>
<span class="token keyword">const</span> plusOne <span class="token operator">=</span> <span class="token function">computed</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> count<span class="token punctuation">.</span>value <span class="token operator">+</span> <span class="token number">1</span><span class="token punctuation">)</span> <span class="token comment">// method</span>
<span class="token keyword">const</span> <span class="token function-variable function">increment</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span> count<span class="token punctuation">.</span>value<span class="token operator">++</span> <span class="token punctuation">}</span>
<span class="token comment">// watch</span>
<span class="token function">watch</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> count<span class="token punctuation">.</span>value \<span class="token operator">*</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token parameter">v</span> <span class="token operator">=&gt;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>v<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token comment">// lifecycle</span>
<span class="token function">onMounted</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'mounted!'</span><span class="token punctuation">)</span><span class="token punctuation">)</span>
<span class="token comment">// 暴露给模版或渲染函数</span>
<span class="token keyword">return</span> <span class="token punctuation">{</span> count <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br></div></div><ul><li>对比 Class API
<ul><li>更灵活的逻辑复用能力</li> <li>更好的 TypeScript 类型推导支持</li> <li>更好的性能</li> <li>Tree-shaking 友好</li> <li>代码更容易被压缩</li></ul></li></ul> <h3 id="关于逻辑复用"><a href="#关于逻辑复用" aria-hidden="true" class="header-anchor">#</a> 关于逻辑复用</h3> <ul><li>Mixin
<ul><li>混入的属性来源不清晰 - 命名空间冲突</li></ul></li> <li>高阶组件 (HOC)
<ul><li>Props 来源不清晰</li> <li>Props 命名空间冲突</li> <li>多余的组件实例 􏰁 成的性能浪 费</li></ul></li> <li>Scoped Slots
<ul><li>来源清晰</li> <li>无命名空 间冲突</li> <li>多余的组件实例 􏰁 成的性能浪 费</li></ul></li></ul> <h3 id="关于逻辑复用-2"><a href="#关于逻辑复用-2" aria-hidden="true" class="header-anchor">#</a> 关于逻辑复用</h3> <ul><li>Composition Functions
<ul><li>就是简单的函数组合</li> <li>无额外的组件实例开销</li> <li>以 “功能” 而不是 “选项” 或 “生命周期” 切分代码
例子:抽取鼠标位置侦听逻辑</li></ul> <div class="language-javascript line-numbers-mode"><pre class="language-javascript"><code><span class="token keyword">function</span> <span class="token function">useMousePosition</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token keyword">const</span> x <span class="token operator">=</span> <span class="token function">value</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  <span class="token keyword">const</span> y <span class="token operator">=</span> <span class="token function">value</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  <span class="token keyword">const</span> <span class="token function-variable function">update</span> <span class="token operator">=</span> <span class="token parameter">e</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
    x<span class="token punctuation">.</span>value <span class="token operator">=</span> e<span class="token punctuation">.</span>pageX<span class="token punctuation">;</span>
    y<span class="token punctuation">.</span>value <span class="token operator">=</span> e<span class="token punctuation">.</span>pageY<span class="token punctuation">;</span>
  <span class="token punctuation">}</span><span class="token punctuation">;</span>
  <span class="token function">onMounted</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
    window<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">&quot;mousemove&quot;</span><span class="token punctuation">,</span> update<span class="token punctuation">)</span><span class="token punctuation">;</span>
  <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  <span class="token function">onUnmounted</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
    window<span class="token punctuation">.</span><span class="token function">removeEventListener</span><span class="token punctuation">(</span><span class="token string">&quot;mousemove&quot;</span><span class="token punctuation">,</span> update<span class="token punctuation">)</span><span class="token punctuation">;</span>
  <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  <span class="token keyword">return</span> <span class="token punctuation">{</span> x<span class="token punctuation">,</span> y <span class="token punctuation">}</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br></div></div></li></ul> <p>例子:抽取鼠标位置侦听逻辑</p> <div class="language-javascript line-numbers-mode"><pre class="language-javascript"><code><span class="token keyword">const</span> App <span class="token operator">=</span> <span class="token punctuation">{</span>
<span class="token function">setup</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">const</span> <span class="token punctuation">{</span> x<span class="token punctuation">,</span> y <span class="token punctuation">}</span> <span class="token operator">=</span> <span class="token function">useMousePosition</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token keyword">const</span> z <span class="token operator">=</span> <span class="token function">useOtherLogic</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
<span class="token keyword">return</span> <span class="token punctuation">{</span>
x<span class="token punctuation">,</span> y<span class="token punctuation">,</span> z
<span class="token punctuation">}</span>
<span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br></div></div><h2 id="对比-react-hooks"><a href="#对比-react-hooks" aria-hidden="true" class="header-anchor">#</a> 对比 React Hooks</h2> <ul><li><p>同样的逻辑复用能力 - 只调用一次</p> <ul><li>符合 JS 直觉</li> <li>没有闭包变量问题</li> <li>没有内存/GC 压力</li> <li>不存在内联回调导致子组件永远更新的问题</li></ul> <p>所有核心改动都已经发布对应 RFC https://github.com/vuejs/rfcs</p> <h1 id="培训-学习路线"><a href="#培训-学习路线" aria-hidden="true" class="header-anchor">#</a> 培训/学习路线</h1></li></ul> <h2 id="新手向的学习路线"><a href="#新手向的学习路线" aria-hidden="true" class="header-anchor">#</a> 新手向的学习路线</h2> <p>https://zhuanlan.zhihu.com/p/23134551</p> <h2 id="已有前端基础的学习路线"><a href="#已有前端基础的学习路线" aria-hidden="true" class="header-anchor">#</a> 已有前端基础的学习路线</h2> <ul><li>通过文档基础部分上手</li> <li>通过实战类的视频课程或是书籍深化理解 - 再过一遍文档，这一遍着重看细节</li> <li>在中小型项目中继续熟悉</li> <li>阅读一些开源组件代码，了解一些高级用法</li> <li>阅读深入内部实现、源码研究类的书籍
<ul><li>推荐两本电子书:Vue 技术内幕 Vue.js 技术揭秘</li></ul></li></ul></div> <div class="page-foot"><span><a href="/post/#Vue">#Vue</a></span></div></div> <div class="page-comment"><!----></div> <!----> </div> <div class="page-right"><div class="toc"><h4>目录</h4> <ul class="toc-wrap"><!----> <ul><li><a href="#良好的反馈">良好的反馈</a></li></ul> <!----> <!----><!----> <ul><li><a href="#对比-angular">对比 Angular</a></li></ul> <!----> <!----><!----> <ul><li><a href="#对比-react">对比 React</a></li></ul> <!----> <!----><!----> <ul><li><a href="#与其它所有框架的区别">与其它所有框架的区别</a></li></ul> <!----> <!----><!----> <ul><li><a href="#官方工具链">官方工具链</a></li></ul> <!----> <!----><!----> <ul><li><a href="#优秀的组件库">优秀的组件库</a></li></ul> <!----> <!----><!----> <ul><li><a href="#优秀的组件库-2">优秀的组件库</a></li></ul> <!----> <!----><!----> <ul><li><a href="#上层框架-nuxt-js">上层框架 - Nuxt.js</a></li></ul> <!----> <!----><!----> <ul><li><a href="#移动端方案-h5-hybrid-vant">移动端方案(H5 / Hybrid) - Vant</a></li></ul> <!----> <!----><!----> <ul><li><a href="#移动端方案-native">移动端方案(Native)</a></li></ul> <!----> <!----><!----> <ul><li><a href="#_3-0-设计目标">3.0 设计目标</a></li></ul> <!----> <!----><!----> <!----> <ul><ul><li><a href="#更小">更小</a></li></ul></ul> <!----><!----> <!----> <ul><ul><li><a href="#更快">更快</a></li></ul></ul> <!----><!----> <!----> <ul><ul><li><a href="#提高自身可维护性">提高自身可维护性</a></li></ul></ul> <!----><!----> <!----> <ul><ul><li><a href="#传统-vdom-的性能瓶颈">传统 vdom 的性能瓶颈</a></li></ul></ul> <!----><!----> <!----> <ul><ul><li><a href="#动静结合突破瓶颈">动静结合突破瓶颈</a></li></ul></ul> <!----><!----> <!----> <ul><ul><li><a href="#动静结合突破瓶颈-2">动静结合突破瓶颈</a></li></ul></ul> <!----><!----> <!----> <ul><ul><li><a href="#typescript">TypeScript</a></li></ul></ul> <!----><!----> <!----> <ul><ul><li><a href="#function-based-api">Function-based API</a></li></ul></ul> <!----><!----> <!----> <ul><ul><li><a href="#关于逻辑复用">关于逻辑复用</a></li></ul></ul> <!----><!----> <!----> <ul><ul><li><a href="#关于逻辑复用-2">关于逻辑复用</a></li></ul></ul> <!----><!----> <ul><li><a href="#对比-react-hooks">对比 React Hooks</a></li></ul> <!----> <!----><!----> <ul><li><a href="#新手向的学习路线">新手向的学习路线</a></li></ul> <!----> <!----><!----> <ul><li><a href="#已有前端基础的学习路线">已有前端基础的学习路线</a></li></ul> <!----> <!----></ul></div></div></main> <footer class="footer" data-v-437632ea><div class="footer-ctx" data-v-437632ea><div class="footer-ctx-l" data-v-437632ea><h5 data-v-437632ea>自述</h5> <p data-v-437632ea>接触前端以来一直想自己设计开发一个博客，用于分想和记录工作、生活和学习中遇到的问题，与解决问题的思路和感悟。 (^o^)/~。</p></div> <div class="footer-ctx-m" data-v-437632ea><h5 data-v-437632ea>相关链接</h5> <ul class="flink" data-v-437632ea><li class="flink-wrap" data-v-437632ea><a href="/" class="dedline" data-v-437632ea>关于我</a></li><li class="flink-wrap" data-v-437632ea><a href="https://github.com/jaykenxie" class="dedline" data-v-437632ea>GitHub</a></li><li class="flink-wrap" data-v-437632ea><a href="https://weibo.com/autoshun" class="dedline" data-v-437632ea>微博</a></li></ul></div> <div class="footer-ctx-r" data-v-437632ea><img src="/images/logo_w.png" alt="Jayken (谢小舜)|谢小舜的个人博客" class="footer-ctx-r_logo" data-v-437632ea></div></div> <div class="footer-info" data-v-437632ea><a href="/" data-v-437632ea>©Jayken</a> <i data-v-437632ea> · </i> <a href="https://v1.vuepress.vuejs.org" data-v-437632ea>Vuepress</a>
      |  
    <a href="http://www.miitbeian.gov.cn/publish/query/indexFirst.action" target="_blank" class="dedline" data-v-437632ea>粤ICP备18012800号-2</a></div></footer></div><div class="global-ui"></div></div>
    <script src="/assets/js/app.2d175a42.js" defer></script><script src="/assets/js/2.af4947b8.js" defer></script><script src="/assets/js/13.71248d26.js" defer></script>
  </body>
</html>
